//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#include "PredictBindingSiteByPattern.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <fstream>
#include <iostream>
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
using namespace std;
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
#define MAX_SIZE 500000
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PredictBindingSiteByPattern::PredictBindingSiteByPattern () {

  this->sequence        = new String ();
  this->header          = new String ();
  
  this->scoreAA         = NULL;
  this->scoreCH         = NULL;
  this->scorePH         = NULL;
  this->scoreSS         = NULL;
  this->scoreMT         = NULL;
  this->scoreCumul      = NULL;
  this->anchorResidues  = NULL;

  this->toString        = new String ();

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PredictBindingSiteByPattern::PredictBindingSiteByPattern (const PredictBindingSiteByPattern& predictBindingSiteByPattern) {

  this->sequence        = new String (predictBindingSiteByPattern.sequence);
  this->header          = new String (predictBindingSiteByPattern.header);

  this->scoreAA         = new float [this->sequence->Length()];
  this->scoreCH         = new float [this->sequence->Length()];
  this->scorePH         = new float [this->sequence->Length()];
  this->scoreSS         = new float [this->sequence->Length()];
  this->scoreMT         = new float [this->sequence->Length()];
  this->scoreCumul      = new float [this->sequence->Length()];
  this->anchorResidues  = new float [this->sequence->Length()];
  
  for (int i = 0; i < this->sequence->Length(); i++) {
    this->scoreAA[i]         = predictBindingSiteByPattern.scoreAA[i];
    this->scoreCH[i]         = predictBindingSiteByPattern.scoreCH[i];
    this->scorePH[i]         = predictBindingSiteByPattern.scorePH[i];
    this->scoreSS[i]         = predictBindingSiteByPattern.scoreSS[i];
    this->scoreMT[i]         = predictBindingSiteByPattern.scoreMT[i];
    this->scoreCumul[i]      = predictBindingSiteByPattern.scoreCumul[i];
    this->anchorResidues[i]  = predictBindingSiteByPattern.anchorResidues[i];
  }

  this->toString        = new String (predictBindingSiteByPattern.toString);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PredictBindingSiteByPattern::PredictBindingSiteByPattern (const PredictBindingSiteByPattern* predictBindingSiteByPattern) {

  this->sequence        = new String (predictBindingSiteByPattern->sequence);
  this->header          = new String (predictBindingSiteByPattern->header);
  
  this->scoreAA         = new float [this->sequence->Length()];
  this->scoreCH         = new float [this->sequence->Length()];
  this->scorePH         = new float [this->sequence->Length()];
  this->scoreSS         = new float [this->sequence->Length()];
  this->scoreMT         = new float [this->sequence->Length()];
  this->scoreCumul      = new float [this->sequence->Length()];
  this->anchorResidues  = new float [this->sequence->Length()];
  
  for (int i = 0; i < this->sequence->Length(); i++) {
    this->scoreAA[i]         = predictBindingSiteByPattern->scoreAA[i];
    this->scoreCH[i]         = predictBindingSiteByPattern->scoreCH[i];
    this->scorePH[i]         = predictBindingSiteByPattern->scorePH[i];
    this->scoreSS[i]         = predictBindingSiteByPattern->scoreSS[i];
    this->scoreMT[i]         = predictBindingSiteByPattern->scoreMT[i];
    this->scoreCumul[i]      = predictBindingSiteByPattern->scoreCumul[i];
    this->anchorResidues[i]  = predictBindingSiteByPattern->anchorResidues[i];
  }

  this->toString        = new String (predictBindingSiteByPattern->toString);

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PredictBindingSiteByPattern::~PredictBindingSiteByPattern () {

  if (this->sequence)       delete this->sequence;
  if (this->header)         delete this->header;
  
  if (this->scoreAA)        delete [] this->scoreAA;
  if (this->scoreCH)        delete [] this->scoreCH;
  if (this->scorePH)        delete [] this->scorePH;
  if (this->scoreSS)        delete [] this->scoreSS;
  if (this->scoreMT)        delete [] this->scoreMT;
  if (this->scoreCumul)     delete [] this->scoreCumul;
  if (this->anchorResidues) delete [] this->anchorResidues;

  if (this->toString)       delete this->toString;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::Sequence (String* sequence) {

  if (sequence)
    *(this->sequence) = *sequence;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::Header (String* header) {

  if (header)
    *(this->header) = *header;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::ScoreAA (float* scoreAA) {

  if (scoreAA)
    this->scoreAA = scoreAA;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::ScoreCH (float* scoreCH) {

  if (scoreCH)
    this->scoreCH = scoreCH;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::ScorePH (float* scorePH) {

  if (scorePH)
    this->scorePH = scorePH;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::ScoreSS (float* scoreSS) {

  if (scoreSS)
    this->scoreSS = scoreSS;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::ScoreMT (float* scoreMT) {

  if (scoreMT)
    this->scoreMT = scoreMT;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::ScoreCumul (float* scoreCumul) {

  if (scoreCumul)
    this->scoreCumul = scoreCumul;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
void PredictBindingSiteByPattern::AnchorResidues (float* anchorResidues) {

  if (anchorResidues) 
    this->anchorResidues = anchorResidues;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PredictBindingSiteByPattern::Sequence (void) {

  return this->sequence;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PredictBindingSiteByPattern::Header (void) {

  return this->header;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float* PredictBindingSiteByPattern::ScoreAA (void) {

  return this->scoreAA;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float* PredictBindingSiteByPattern::ScoreCH (void) {

  return this->scoreCH;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float* PredictBindingSiteByPattern::ScorePH (void) {

  return this->scorePH;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float* PredictBindingSiteByPattern::ScoreSS (void) {

  return this->scoreSS;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float* PredictBindingSiteByPattern::ScoreMT (void) {

  return this->scoreMT;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float* PredictBindingSiteByPattern::ScoreCumul (void) {

  return this->scoreCumul;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
float* PredictBindingSiteByPattern::AnchorResidues (void) {

  return this->anchorResidues;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PredictBindingSiteByPattern::LoadDataFromString (String* data) {

  if (!data) return false;
  
  this->header->In("");
  this->sequence->In("");
  
  if (this->scoreAA)        delete [] this->scoreAA;
  if (this->scoreCH)        delete [] this->scoreCH;
  if (this->scorePH)        delete [] this->scorePH;
  if (this->scoreSS)        delete [] this->scoreSS;
  if (this->scoreMT)        delete [] this->scoreMT;
  if (this->scoreCumul)     delete [] this->scoreCumul;
  if (this->anchorResidues) delete [] this->anchorResidues;
  
  char*   part     = NULL;
  String  sequence;
  String  scoreAA;
  String  scoreCH;
  String  scorePH;
  String  scoreSS;
  String  scoreMT;
  String  scoreCumul;
  String  anchorResidues;
  
  if ((part = strtok(data->Out(), "\n")) != NULL) this->header->In(part);   else return false;
  
  if ((part = strtok(NULL,        "\n")) != NULL) sequence.In(part);        else return false;
  if ((part = strtok(NULL,        "\n")) != NULL) scoreAA.In(part);         else return false;
  if ((part = strtok(NULL,        "\n")) != NULL) scoreCH.In(part);         else return false;
  if ((part = strtok(NULL,        "\n")) != NULL) scorePH.In(part);         else return false;
  if ((part = strtok(NULL,        "\n")) != NULL) scoreSS.In(part);         else return false;
  if ((part = strtok(NULL,        "\n")) != NULL) scoreMT.In(part);         else return false;
  if ((part = strtok(NULL,        "\n")) != NULL) scoreCumul.In(part);      else return false;
  if ((part = strtok(NULL,        "\n")) != NULL) anchorResidues.In(part);  else return false;

  this->sequence->In("");
  part = strtok(sequence.Out(), ";");
  while (part) {
    this->sequence->Add(part);
    part = strtok(NULL, ";");
  }
  
  this->scoreAA         = new float [this->sequence->Length()];
  this->scoreCH         = new float [this->sequence->Length()];
  this->scorePH         = new float [this->sequence->Length()];
  this->scoreSS         = new float [this->sequence->Length()];
  this->scoreMT         = new float [this->sequence->Length()];
  this->scoreCumul      = new float [this->sequence->Length()];
  this->anchorResidues  = new float [this->sequence->Length()];
  
  for (int i = 0; i < 7; i++) 
    for (int j = 0; j < this->sequence->Length(); j++) 
      switch (i) {
        case 0 : this->scoreAA[j]        = ((part = strtok(((!j)?scoreAA.Out():NULL),        ";")) != NULL)?atof(part):0; break;
        case 1 : this->scoreCH[j]        = ((part = strtok(((!j)?scoreCH.Out():NULL),        ";")) != NULL)?atof(part):0; break;
        case 2 : this->scorePH[j]        = ((part = strtok(((!j)?scorePH.Out():NULL),        ";")) != NULL)?atof(part):0; break;
        case 3 : this->scoreSS[j]        = ((part = strtok(((!j)?scoreSS.Out():NULL),        ";")) != NULL)?atof(part):0; break;
        case 4 : this->scoreMT[j]        = ((part = strtok(((!j)?scoreMT.Out():NULL),        ";")) != NULL)?atof(part):0; break;
        case 5 : this->scoreCumul[j]     = ((part = strtok(((!j)?scoreCumul.Out():NULL),     ";")) != NULL)?atof(part):0; break;
        case 6 : this->anchorResidues[j] = ((part = strtok(((!j)?anchorResidues.Out():NULL), ";")) != NULL)?atof(part):0; break;
      }
  
  return true;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String* PredictBindingSiteByPattern::ToString (void) {

  int type = 1;
  
  this->toString->In("");
  
  this->toString->Add(this->Header());
  this->toString->Add("\n");
  this->toString->Add(this->OutFormatedArray(this->Sequence(), type).Out());
  this->toString->Add("\n");
  this->toString->Add(this->OutFormatedArray(this->ScoreAA(),        this->Sequence()->Length(), type).Out());
  this->toString->Add("\n");
  this->toString->Add(this->OutFormatedArray(this->ScoreCH(),        this->Sequence()->Length(), type).Out());
  this->toString->Add("\n");
  this->toString->Add(this->OutFormatedArray(this->ScorePH(),        this->Sequence()->Length(), type).Out());
  this->toString->Add("\n");
  this->toString->Add(this->OutFormatedArray(this->ScoreSS(),        this->Sequence()->Length(), type).Out());
  this->toString->Add("\n");
  this->toString->Add(this->OutFormatedArray(this->ScoreMT(),        this->Sequence()->Length(), type).Out());
  this->toString->Add("\n");
  this->toString->Add(this->OutFormatedArray(this->ScoreCumul(),     this->Sequence()->Length(), type).Out());
  this->toString->Add("\n");
  this->toString->Add(this->OutFormatedArray(this->AnchorResidues(), this->Sequence()->Length(), type).Out());
  this->toString->Add("\n");

  return this->toString;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String PredictBindingSiteByPattern::OutFormatedArray (String* data, int type) {
  
  String out;
  char   buffer [MAX_SIZE];
  
  out.In("");
  if (data)
    for (long i = 0; i < data->Length(); i++) {
      if (!type) sprintf(buffer, "%c      \0", data->Out()[i]);
      else       sprintf(buffer, (!i)?"%c\0":";%c\0", data->Out()[i]);
      out.Add(buffer);
    }
    
  return out;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
String PredictBindingSiteByPattern::OutFormatedArray (float* data, int size, int type) {
  
  String out;
  char   buffer [MAX_SIZE];
  
  out.In("");
  if (data)
    for (long i = 0; i < size; i++) {
      if (!type) sprintf(buffer, "%3.2f \0", data[i]);
      else       sprintf(buffer, (!i)?"%3.2f\0":";%3.2f\0", data[i]);
      out.Add(buffer);
    }
    
  return out;
  
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
bool PredictBindingSiteByPattern::AllocateMemoryForScore (int size) {
  
  this->scoreAA         = new float [size];
  this->scoreCH         = new float [size];
  this->scorePH         = new float [size];
  this->scoreSS         = new float [size];
  this->scoreMT         = new float [size];
  this->scoreCumul      = new float [size];
  this->anchorResidues  = new float [size];
  
  for (int i = 0; i < this->sequence->Length(); i++)
    this->scoreAA[i] = this->scoreCH[i] = this->scorePH[i] = this->scoreSS[i] = this->scoreMT[i] = this->scoreCumul[i] = this->anchorResidues[i] = 0;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
PredictBindingSiteByPattern PredictBindingSiteByPattern::operator= (const PredictBindingSiteByPattern& predictBindingSiteByPattern) {

  *(this->sequence)       = *(predictBindingSiteByPattern.sequence);
  *(this->header )        = *(predictBindingSiteByPattern.header);
  
  if (this->scoreAA)        delete [] this->scoreAA;
  if (this->scoreCH)        delete [] this->scoreCH;
  if (this->scorePH)        delete [] this->scorePH;
  if (this->scoreSS)        delete [] this->scoreSS;
  if (this->scoreMT)        delete [] this->scoreMT;
  if (this->scoreCumul)     delete [] this->scoreCumul;
  if (this->anchorResidues) delete [] this->anchorResidues;

  this->scoreAA         = new float [this->sequence->Length()];
  this->scoreCH         = new float [this->sequence->Length()];
  this->scorePH         = new float [this->sequence->Length()];
  this->scoreSS         = new float [this->sequence->Length()];
  this->scoreMT         = new float [this->sequence->Length()];
  this->scoreCumul      = new float [this->sequence->Length()];
  this->anchorResidues  = new float [this->sequence->Length()];
  
  for (int i = 0; i < this->sequence->Length(); i++) {
    *(this->scoreAA + i)         = *(predictBindingSiteByPattern.scoreAA + i);
    *(this->scoreCH + i)         = *(predictBindingSiteByPattern.scoreCH + i);
    *(this->scorePH + i)         = *(predictBindingSiteByPattern.scorePH + i);
    *(this->scoreSS + i)         = *(predictBindingSiteByPattern.scoreSS + i);
    *(this->scoreMT + i)         = *(predictBindingSiteByPattern.scoreMT + i);
    *(this->scoreCumul + i)      = *(predictBindingSiteByPattern.scoreCumul + i);
    *(this->anchorResidues + i)  = *(predictBindingSiteByPattern.anchorResidues + i);
  }

  return *this;

}
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------------------------------------------------------------------------------------------------//
